/*
project: valid8
r: 11.19.2009
author: Jamison Morrow
project home: http://code.google.com/p/javascript-validation-form/
license: MIT, http://www.opensource.org/licenses/mit-license.php
*/

var valid8 = { elementsToCheck: {}, validators: new Array() };

/*
FOCUS ON DOC LOAD
*/
$(document).ready(function() { $(".valid8_focus:visible").focus() });

/*
ERROR MESSAGES
*/
valid8.requiredError = function(name) { return name + " is required." };
valid8.minLengthError = function(name, len) { return name + " must be at least " + len + " characters." };
valid8.maxLengthError = function(name, len) { return name + " cannot be longer than " + len + " characters." };
valid8.invalidValueError = function(name, value) { return "'" + value + "' is not a valid value for " + name + "." };
valid8.invalidPhoneError = function(name) { return name + " must contain at least 10 digits" };
valid8.checkBoxError = function(name) { return name + " must be checked." };
valid8.matchingFieldsError = function(name) { return name + " does not match." };

/*
REG EXPRESSIONS
*/
valid8.phoneRegex = new RegExp("([0-9].?){10}", "gi");
valid8.emailRegex = new RegExp("^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$", "gi");

/*
REGISTERS A VALIDATOR
*/
valid8.add = function(type/*validation function*/, params/*object*/)
{
    //additional attributes
    params.field = $("[name='" + params.element + "']");
    params.name = params.field.attr("name");
    params.label = $("label[for='" + params.name + "']").text();
    params.form = params.field[0].form;

    //if validation event not already registered
    if (!valid8.elementsToCheck[params.name])
    {
        params.field.bind(params.event || "change", params.name, valid8.checkField);
        valid8.elementsToCheck[params.name] = true;
    }

    //decorate
    params.field.addClass("valid8_mustValidate");

    //max length?
    if (params.maxLength) params.field.attr("maxLength", params.maxLength);

    //add it
    valid8.validators.push({ type: type, params: params, form: params.form });
};

/*
RESETS VALIDATION
*/
valid8.reset = function()
{
    valid8.elementsToCheck = {};
    valid8.validators = new Array();
}

/*
CHECKS A FIELD FOR VALIDITY
*/
valid8.checkField = function(event/*DOMEvent*/)
{
    for (var i = 0; i < valid8.validators.length; i++)
    {
        var v = valid8.validators[i];
        if (v.params.name == event.data && v.params.field.is(":visible") && !v.type(v.params))
            return;
    }
};

/*
A VALIDIDATOR FOR STRINGS
*/
valid8.stringValidator = function(params/*object*/)
{
    var val = params.field.val();

    //required field
    if (params.required && val.length == 0)
    {
        valid8.setInvalid(params.field, params.requiredError || valid8.requiredError(params.label));
        return false;
    }

    //min length
    if (params.minLength && val.length < params.minLength)
    {
        valid8.setInvalid(params.field, params.minLengthError || valid8.minLengthError(params.label, params.minLength));
        return false;
    }

    //max length
    if (params.maxLength && val.length > params.maxLength)
    {
        valid8.setInvalid(params.field, params.maxLengthError || valid8.maxLengthError(params.label, params.maxLength));
        return false;
    }

    //regex
    if (params.regex && !params.regex.test(val))
    {
        valid8.setInvalid(params.field, params.invalidValueError || valid8.invalidValueError(params.label, val));
        return false;
    }

    valid8.setValid(params.field);
    return true;
};

/*
A VALIDIDATOR FOR CHECKBOXES
*/
valid8.checkboxValidator = function(params/*object*/)
{
    if (!params.field.is(":checked"))
    {
        valid8.setInvalid(params.field, params.checkBoxError || valid8.checkBoxError(params.label));
        return false;
    }
    valid8.setValid(params.field);
    return true;
};

/*
A VALIDIDATOR FOR PASSWORD MATCHING
*/
valid8.matchValidator = function(params/*object*/)
{
    if (params.field.val() != $("[name='" + params.elementToMatch + "']").val())
    {
        valid8.setInvalid(params.field, params.matchingFieldsError || valid8.matchingFieldsError(params.label));
        return false;
    }
    valid8.setValid(params.field);
    return true;
};

/*
SETS A FIELD TO VALID STATUS
*/
valid8.setValid = function(field/*jquery*/)
{
    //set field to valid
    field.removeClass("valid8_invalid").removeClass("valid8_mustValidate"); //.addClass("valid8_valid");

    //add valid box
    var id = field.attr("name") + "_valid";
    if ($("#" + id).length == 0)
    {
        var validImg = $("<img src='http://javascript-validation-form.googlecode.com/files/valid.png' class='valid8_valid'/>");
        validImg.attr("id", id);
        field.after(validImg);
    }

    //remove error div (if exists)
    $("#" + field.attr("name") + "_error").remove();
};

/*
SETS A FIELD TO INVALID STATUS
*/
valid8.setInvalid = function(field/*jquery*/, message/*string*/)
{
    //error div name
    var errorId = field.attr("name") + "_error";

    //set field to invalid
    field.addClass("valid8_invalid").removeClass("valid8_mustValidate");

    //remove any "valid" images
    $("#" + field.attr("name") + "_valid").remove();

    //remove any existing error divs
    $("#" + errorId).remove();

    //show error div (if not already there)
    var pos = field.position();
    var errorDiv = $("<span class='valid8_error'/>");
    errorDiv.attr("id", errorId).html(message).css("top", pos.top).css("left", pos.left + field.width());
    $(field).after(errorDiv);
};

/*
VALIDATES A FORM IF NEEDED, AND RETURNS THE RESULTS
*/
valid8.isValid = function(form/*form element*/)
{
    $(form).find(".valid8_mustValidate:visible").each(function()
    {
        for (var i = 0; i < valid8.validators.length; i++)
        {
            if (valid8.validators[i].params.name == this.name)
                valid8.checkField({ data: this.name });
        }
    });

    //get invalid or unchecked
    var invalids = $(form).find(".valid8_invalid:visible,.valid8_mustValidate:visible");

    if (invalids.length == 0) return true;
    else
    {
        invalids[0].focus();
        return false;
    }
};

/*
SHOWS THE "LOADING" ANIMATION
*/
valid8.showLoader = function(field/*jQuery*/)
{
    //hide valid and invalid divs for this field
    var validId = field[0].name + "_valid";
    var invalidId = field[0].name + "_invalid";
    $("#" + validId + ",#" + invalidId).remove();

    //show loader
    var loader = $("<img src='http://javascript-validation-form.googlecode.com/files/loading.gif' class='valid8_loading' />");
    loader.attr("id", field[0].name + "_loading");
    field.after(loader);
};

/*
HIDES THE "LOADING" ANIMATION
*/
valid8.hideLoader = function(field/*jQuery*/)
{
    $("#" + field[0].name + "_loading").remove();
}